1211. Бесконечная последовательность

 

Определим бесконечную последовательность А следующим образом:

A0 = 1,

Ai = A[i/p] + A[i/q] , i ³ 1

По заданным n, p, q необходимо вычислить An.

 

Вход. Три целых числа n, p, q (0 £ n £ 1012, 2 £ p, q £ 109).

 

Выход. Значение An.

 

Пример входа 1

Пример выхода 1

0 2 3

1

 

 

Пример входа 2

Пример выхода 2

10000000 3 3

32768

 

 

РЕШЕНИЕ

структуры данных – map, рекурсия

 

Анализ алгоритма

Вычислить все значения Ai (i = 0, 1, …, n) последовательности невозможно при помощи массива из-за ограничения n £ 1012. Для запоминания результатов будем использовать структуру map: значение Ai будем хранить в m[i]. Находим значение An, запоминая промежуточные результаты.

 

Реализация алгоритма

Для хранения значений Ai объявим переменную m.

 

map<long long,long long> m;

 

Функция calc возвращает значение m[n].

 

long long calc(long long n, int p, int q)

{

  if (n == 0) return 1;

  if (m.count(n) > 0) return m[n];

  return m[n] = calc(n/p,p,q) + calc(n/q,p,q);

}

 

Основная часть программы. Читаем входные данные. Вычисляем и выводим ответ.

 

scanf("%lld %lld %lld",&n,&p,&q);

res = calc(n,p,q);

printf("%lld\n",res);

 

Java реализация

 

import java.util.*;

 

public class Main

{

  static Map<Long, Long> m = new HashMap<Long, Long>();

 

  public static long calc(long n, long p, long q)

  {

    if (m.containsKey(n)) return m.get(n);

    if (n == 0) return 1;

    long res = calc(n/p,p,q) + calc(n/q,p,q);

    m.put(n,res);

    return res;

  }

 

  public static void main(String[] args)

  {

    Scanner con = new Scanner(System.in);

    long n = con.nextLong(),

         p = con.nextLong(),

         q = con.nextLong();

    System.out.println(calc(n,p,q));

  }

}